home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / WINSYS.PAK / STRING.H < prev    next >
C/C++ Source or Header  |  1997-05-06  |  13KB  |  562 lines

  1. //----------------------------------------------------------------------------
  2. // Borland WinSys Library
  3. // Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   5.9  $
  6. //
  7. // Definition of class TString, a flexible universal string envelope class.
  8. // Facilitates efficient construction and assignment of many string types
  9. //----------------------------------------------------------------------------
  10. #if !defined(WINSYS_STRING_H)
  11. #define WINSYS_STRING_H
  12.  
  13. #if !defined(WINSYS_DEFS_H)
  14. # include <winsys/defs.h>
  15. #endif
  16. #if !defined(SERVICES_OLE2INC_H)
  17. # include <services/ole2inc.h>
  18. #endif
  19. #if !defined(SERVICES_MEMORY_H)
  20. # include <services/memory.h>
  21. #endif
  22.  
  23. #if !defined(BI_PLAT_MSW)
  24. # error Locale classes are only supported under MSW
  25. #endif
  26.  
  27. #if !defined(WINSYS_LCLSTRNG_H)
  28. # include <winsys/lclstrng.h>
  29. #endif
  30. #if !defined(SERVICES_CSTRING_H)
  31. # include <services/cstring.h>
  32. #endif
  33.  
  34. #if defined(BI_NAMESPACE)
  35. namespace ClassLib {
  36. #endif
  37.  
  38. //
  39. // class TSysStr
  40. // ~~~~~ ~~~~~~~
  41. // System string (BSTR) encapsulation. Also gives BSTRs a unique type
  42. // Always assumes ownership of the BSTR, use Relinquish to take BSTR away.
  43. //
  44. class TSysStr {
  45.   public:
  46.     TSysStr() : P(0) {}
  47.     TSysStr(const BSTR p) : P(p) {}
  48.     TSysStr(const TSysStr& src) : P(::SysAllocString(src.P)) {}
  49.  
  50.    ~TSysStr() {if (P) ::SysFreeString(P);}
  51.  
  52.     int    operator !() const {return P == 0;}
  53.     operator const BSTR() const {return P;}
  54.     operator BSTR() {return P;}
  55.  
  56.     TSysStr& operator =(BSTR p) {if (P) ::SysFreeString(P); P = p; return *this;}
  57.     operator BSTR far*() {if (P) {::SysFreeString(P); P = 0;} return &P;}
  58.  
  59.     BSTR   Relinquish() {BSTR p = P; P = 0; return p;}
  60.  
  61.   protected:
  62.     BSTR P;
  63.  
  64.   private:
  65.     void* operator new(size_t) {return 0;} // prohibit use of new, delete, etc
  66.     void  operator delete(void*) {}
  67. };
  68.  
  69. class TUString;
  70.  
  71. //
  72. // class TString
  73. // ~~~~~ ~~~~~~~
  74. // Reference to reference counted string object TUString
  75. // Lightweight reference object consisting of a pointer to actual object
  76. // Facilitates copying and assignment with minimal string reallocations
  77. //
  78. class TString {
  79.   public:
  80.     // Construct a TString from any type of string
  81.     //
  82.     TString(const _TCHAR far* s = 0);
  83. #if defined(BI_HAS_WCHAR)
  84.     TString(const wchar_t* s);
  85. #endif
  86.     TString(BSTR s, bool loan);
  87.     TString(TSysStr& s, bool loan);
  88.     TString(const string& s);
  89.     TString(TUString* s);
  90.     TString(const TString& src);
  91.  
  92.    ~TString();
  93.  
  94.     // Information
  95.     //
  96.     int  Length() const;        // The length in characters of this string
  97.     bool IsNull() const;        // Is the string NULL?
  98.     bool IsWide() const;        // Are the string contents any kind of wide?
  99.  
  100.     // Assign any type of string into this TString
  101.     //
  102.     TString& operator =(const TString& s);
  103.     TString& operator =(const string& s);
  104.     TString& operator =(const _TCHAR far* s);
  105.     TString& operator =(_TCHAR* s);
  106. #if defined(BI_HAS_WCHAR)
  107.     TString& operator =(const wchar_t* s);
  108.     TString& operator =(wchar_t* s);
  109. #endif
  110.  
  111.     // Convert this TString into the desired string type & return pointer into
  112.     // this TString
  113.     //
  114.     operator const _TCHAR far*() const;
  115.     operator _TCHAR*();
  116. #if defined(BI_HAS_WCHAR)
  117.     operator const wchar_t*() const;
  118.     operator wchar_t*();
  119. #endif
  120.  
  121.     // Relinquish ownership and return contents of this TString. Caller then
  122.     // owns the string & must delete or free it.
  123.     //
  124.     BSTR     RelinquishSysStr() const;
  125. #if defined(BI_HAS_WCHAR)
  126.     wchar_t* RelinquishWide() const;
  127. #endif
  128.     _TCHAR*    RelinquishNarrow() const;
  129. #if 1 
  130.     _TCHAR*    Relinquish() const;
  131. #else
  132.     wchar_t* Relinquish() const;
  133. #endif
  134.  
  135.     // Language related
  136.     //
  137.     TLangId GetLangId();
  138.     void    SetLangId(TLangId id);
  139.  
  140.   protected:
  141.     TUString* S;
  142. };
  143.  
  144. //
  145. // Provide ANSI to Wide conversion when OLE requires wide chars
  146. // Allocate a unicode BSTR from an ANSI char*
  147. //
  148. #if defined(BI_OLECHAR_WIDE)
  149. # define OleStr(s) TString(s)
  150. # define OleText(s) L##s
  151.   inline BSTR SysAllocString(const char far* str) {
  152.     return ::SysAllocString((const wchar_t*)TString(str));
  153.   }
  154. #else
  155. # define OleStr(s) s
  156. # define OleText(s) s
  157. #endif
  158.  
  159. //----------------------------------------------------------------------------
  160.  
  161. //
  162. // class TUString
  163. // ~~~~~ ~~~~~~~~
  164. // Privately used by TString to manage string pointers
  165. // This is a reference counted union of various string representatons
  166. // Constructors/destructors are private to enforce reference count model
  167. // Create functions are used to facilitate rapid allocation schemes
  168. // Null pointers are never stored; instead a static null object is ref'd
  169. //
  170. class TUString {
  171.   public:
  172.     static TUString* Create(const _TCHAR far* str);
  173.     static TUString* Create(_TCHAR* str);
  174. #if defined(BI_HAS_WCHAR)
  175.     static TUString* Create(const wchar_t* str);
  176.     static TUString* Create(wchar_t* str);
  177. #endif
  178.     static TUString* Create(TSysStr& str, bool loan, TLangId lang = 0);
  179.     static TUString* Create(BSTR str, bool loan, TLangId lang = 0);
  180.     static TUString* Create(const string& str);
  181.  
  182.     TUString* Assign(const TUString& s);
  183.     TUString* Assign(const string& s);
  184.     TUString* Assign(const _TCHAR far* s);
  185.     TUString* Assign(_TCHAR* s);
  186. #if defined(BI_HAS_WCHAR)
  187.     TUString* Assign(const wchar_t* s);
  188.     TUString* Assign(wchar_t* s);
  189. #endif
  190.     TUString* Assign(BSTR str, TLangId lang);
  191.  
  192.     operator const _TCHAR far*() const;
  193.     operator _TCHAR*();
  194. #if defined(BI_HAS_WCHAR)
  195.     operator const wchar_t*() const;
  196.     operator wchar_t*();
  197. #endif
  198.  
  199.     TUString& operator ++();    // Preincrement operator only
  200.     TUString& operator --();    // Predecrement operator only
  201.  
  202.     int  Length() const;        // Return appropriate string length
  203.     bool IsNull() const;        // Is the string a null string?
  204.     bool IsWide() const;        // Are the string contents any kind of wide?
  205.  
  206.     TLangId Lang;
  207.     void RevokeBstr(BSTR s);    // Used to restore if Created with loan==true
  208.     void ReleaseBstr(BSTR s);   // Used to unhook  if Created with loan==true
  209.  
  210. #if defined(BI_HAS_WCHAR)
  211.     static wchar_t* ConvertAtoW(const char* src, size_t len = -1);
  212.     static char* ConvertWtoA(const wchar_t* src, size_t len = -1);
  213. #endif
  214.  
  215. #if defined(BI_COMP_MSC)    // MSC can't handle the dtor being private
  216.   public:
  217. #else
  218.   private:
  219. #endif
  220.    ~TUString() {Free();}
  221.  
  222.   private:
  223.     TUString(const _TCHAR far& str);
  224.     TUString(_TCHAR& str);
  225. #if defined(BI_HAS_WCHAR)
  226.     TUString(const wchar_t& str);
  227.     TUString(wchar_t& str);
  228. #endif
  229.     TUString(TSysStr& str, bool loan, TLangId lang);
  230.     TUString(BSTR str, bool loan, TLangId lang);
  231.     TUString(const string& str);
  232.  
  233.     void Free();
  234.  
  235.     _TCHAR*    ChangeToCopy();
  236. #if defined(BI_HAS_WCHAR)
  237.     wchar_t* ChangeToWCopy();
  238. #endif
  239.  
  240.     enum TKind {
  241.       isNull,
  242.       isConst, isCopy,
  243.       isWConst, isWCopy,
  244.       isBstr, isExtBstr,
  245.       isString,
  246.     } Kind : 16;
  247.     int16 RefCnt;
  248.     union {
  249.       const _TCHAR far* Const;  // Passed-in string, NOT owned here, read-only
  250.       _TCHAR* Copy;             // Local copy, must be deleted, read-write
  251. #if defined(BI_HAS_WCHAR)
  252.       const wchar_t* WConst;  // Unicode version of Const (Win32)
  253.       wchar_t* WCopy;         // Unicode version of Copy (Win32)
  254. #endif
  255.       BSTR Bstr;              // Copy of pointer, owned here
  256.       TStringRef* String;     // Placeholder for string:: object
  257.     };
  258.  
  259.     static TUString Null;     // Null TString references this
  260.     TUString() : Kind(isNull),Const(0),RefCnt(1),Lang(0) {} // for Null object
  261.  
  262.   friend class TString;       // Envelope string class
  263. };
  264.  
  265. #if defined(BI_NAMESPACE)
  266. }     // namespace ClassLib
  267. #endif
  268.  
  269. //----------------------------------------------------------------------------
  270. // Inlines
  271. //
  272.  
  273. //
  274. // Construct a TString from a character array
  275. //
  276. inline TString::TString(const _TCHAR far* s)
  277. :
  278.   S(TUString::Create(s))
  279. {
  280. }
  281.  
  282. #if defined(BI_HAS_WCHAR)
  283. //
  284. // Construct a TString from a wide character array
  285. //
  286. inline TString::TString(const wchar_t* s)
  287. :
  288.   S(TUString::Create(s))
  289. {
  290. }
  291. #endif
  292.  
  293. //
  294. // Construct a TString from a BSTR (OLE String)
  295. //
  296. inline TString::TString(BSTR s, bool loan)
  297. :
  298.   S(TUString::Create(s, loan))
  299. {
  300. }
  301.  
  302. //
  303. // Construct a TString from a System string (BSTR)
  304. //
  305. inline TString::TString(TSysStr& s, bool loan)
  306. :
  307.   S(TUString::Create(s, loan))
  308. {
  309. }
  310.  
  311. //
  312. // Construct a TString from a string
  313. //
  314. inline TString::TString(const string& s)
  315. :
  316.   S(TUString::Create(s))
  317. {
  318. }
  319.  
  320. //
  321. // Construct a TString from a TUString
  322. //
  323. inline TString::TString(TUString* s)
  324. :
  325.   S(s)
  326. {
  327. }
  328.  
  329. //
  330. // Construct a TString from a TString (Copy Constructor)
  331. //
  332. inline TString::TString(const TString& src)
  333. :
  334.   S(src.S)
  335. {
  336.   ++*S;
  337. }
  338.  
  339. //
  340. // Destruct a TString (actually decrements a reference counter)
  341. //
  342. inline TString::~TString()
  343. {
  344.   --*S;
  345. }
  346.  
  347. //
  348. // Return the length of the string
  349. //
  350. inline int TString::Length() const
  351. {
  352.   return S->Length();
  353. }
  354.  
  355. //
  356. // Return true if string is empty
  357. //
  358. inline bool TString::IsNull() const
  359. {
  360.   return S->IsNull();
  361. }
  362.  
  363. //
  364. // Return true if string uses wide character set
  365. //
  366. inline bool TString::IsWide() const
  367. {
  368.   return S->IsWide();
  369. }
  370.  
  371. //
  372. // Copy contents of TString s into this string
  373. //
  374. inline TString& TString::operator =(const TString& s)
  375. {
  376.   S = S->Assign(*s.S); return *this;
  377. }
  378.  
  379. //
  380. // Copy contents of string s into this string
  381. //
  382. inline TString& TString::operator =(const string& s)
  383. {
  384.   S = S->Assign(s); return *this;
  385. }
  386.  
  387. //
  388. // Copy contents of const char* s into this string
  389. //
  390. inline TString& TString::operator =(const _TCHAR far* s)
  391. {
  392.   S = S->Assign(s); return *this;
  393. }
  394.  
  395. //
  396. // Copy contents of char* s into this string
  397. //
  398. inline TString& TString::operator =(_TCHAR* s)
  399. {
  400.   S = S->Assign(s); return *this;
  401. }
  402.  
  403. #if defined(BI_HAS_WCHAR)
  404.  
  405. //
  406. // Copy contents of const wchar_t* s into this string
  407. //
  408. inline TString& TString::operator =(const wchar_t* s)
  409. {
  410.   S = S->Assign(s); return *this;
  411. }
  412.  
  413. //
  414. // Copy contents of wchar_t* s into this string
  415. //
  416. inline TString& TString::operator =(wchar_t* s)
  417. {
  418.   S = S->Assign(s); return *this;
  419. }
  420. #endif
  421.  
  422. //
  423. // Return string as a const char far*
  424. //
  425. inline TString::operator const _TCHAR far*() const
  426. {
  427.   return S->operator const _TCHAR far*();
  428. }
  429.  
  430. //
  431. // Return string as a char*
  432. //
  433. inline TString::operator _TCHAR*()
  434. {
  435.   return S->operator _TCHAR*();
  436. }
  437.  
  438. #if defined(BI_HAS_WCHAR)
  439.  
  440. //
  441. // Return string as a const wchar_t*
  442. //
  443. inline TString::operator const wchar_t*() const
  444. {
  445.   return S->operator const wchar_t*();
  446. }
  447.  
  448. //
  449. // Return string as a wchar_t*
  450. //
  451. inline TString::operator wchar_t*()
  452. {
  453.   return S->operator wchar_t*();
  454. }
  455. #endif
  456.  
  457. //
  458. // Return a pointer (BSTR) to a copy of the string
  459. //
  460. inline BSTR TString::RelinquishSysStr() const
  461. {
  462. #if defined(BI_OLECHAR_WIDE)
  463.   return ::SysAllocString((const wchar_t*)*S);
  464. #else
  465.   return ::SysAllocString((const _TCHAR*)*S);
  466. #endif
  467. }
  468.  
  469. #if defined(BI_HAS_WCHAR)
  470. //
  471. // Return a pointer (wchar_t*) to a copy of the string
  472. //
  473. inline wchar_t* TString::RelinquishWide() const
  474. {
  475.   return strnewdup((const wchar_t*)*S);
  476. }
  477. #endif
  478.  
  479. //
  480. // Return a pointer (char*) to a copy of the string
  481. //
  482. inline _TCHAR* TString::RelinquishNarrow() const
  483. {
  484.   return strnewdup((const _TCHAR*)*S);
  485. }
  486.  
  487. //
  488. // Return a pointer (char*) to a copy of the string
  489. //
  490. #if 1 
  491. inline _TCHAR* TString::Relinquish() const
  492. {
  493.   return RelinquishNarrow();
  494. }
  495. #else
  496. inline wchar_t* TString::Relinquish() const
  497. {
  498.   return RelinquishWide();
  499. }
  500. #endif
  501.  
  502. //
  503. // Get Language Id of this string
  504. //
  505. inline TLangId TString::GetLangId()
  506. {
  507.   return S->Lang;
  508. }
  509.  
  510.  
  511. //
  512. // Set Language Id of this string
  513. //
  514. inline void TString::SetLangId(TLangId id)
  515. {
  516.   S->Lang = id;
  517. }
  518.  
  519. //----------------------------------------------------------------------------
  520.  
  521. //
  522. // Increment reference counter for this string
  523. //
  524. inline TUString& TUString::operator ++()
  525. {
  526.   ++RefCnt;
  527.   return *this;
  528. }
  529.  
  530. //
  531. // Decrement reference counter for this string
  532. //
  533. inline TUString& TUString::operator --()
  534. {
  535.   if (--RefCnt != 0)
  536.     return *this;
  537.   delete this;
  538.   return Null;
  539. }
  540.  
  541. //
  542. // Return true if string is empty
  543. //
  544. inline bool TUString::IsNull() const
  545. {
  546.   return Kind == isNull;
  547. }
  548.  
  549. //
  550. // Return true if string uses wide character set
  551. //
  552. inline bool TUString::IsWide() const
  553. {
  554. #if defined(BI_OLECHAR_WIDE)
  555.   return Kind == isWConst || Kind == isWCopy || Kind == isBstr || Kind == isExtBstr;
  556. #else
  557.   return Kind == isWConst || Kind == isWCopy;
  558. #endif
  559. }
  560.  
  561. #endif  // WINSYS_STRING_H
  562.